package me.minecraft.plugin.pokemonconverter.listener;

import com.cobblemon.mod.common.pokemon.Pokemon;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lg.minecraft.plugin.cobblemoncore.util.BukkitNmsConverter;
import lg.minecraft.plugin.cobblemoncore.util.CobblemonType;
import lg.minecraft.plugin.pokemonmenu.LGPokemonMenu;
import lg.minecraft.plugin.pokemonmenu.PokemonPlayer;
import lg.minecraft.plugin.pokemonmenu.event.EventFactory;
import lg.minecraft.plugin.pokemonmenu.event.ItemToPokemonEvent;
import lg.minecraft.plugin.pokemonmenu.gui.ItemToPokemonInventory;
import lg.minecraft.plugin.pokemonmenu.manager.PokemonPlayerManger;
import lg.minecraft.plugin.pokemonmenu.util.PokemonNBTUtil;
import lombok.SneakyThrows;
import me.minecraft.plugin.pokemonconverter.config.MainConfig;
import net.minecraft.*;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.util.Base64;
import java.util.Optional;

/**
 * @author langle__
 * @version 1.0
 */
public class PlayerEvent implements Listener {

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        Player player = event.getPlayer();
        EquipmentSlot hand = event.getHand();
        Action action = event.getAction();
        PlayerInventory inventory = player.getInventory();
        ItemStack bukkitItem = inventory.getItemInMainHand();

        if (hand != EquipmentSlot.HAND || (action != Action.RIGHT_CLICK_AIR && action != Action.RIGHT_CLICK_BLOCK) || bukkitItem.getType() != CobblemonType.COBBLEMON_POKEMON_MODEL_TYPE) return;

        class_1799 item = BukkitNmsConverter.toItemStack(bukkitItem);
        class_9279 class9279 = item.method_57353().method_57829(class_9334.field_49628);
        if (class9279 == null) return;

        Optional<class_9279> customData = Optional.of(class9279);
        class_2487 nbt = customData.get().method_57461();

        PokemonNBTUtil.Entry entry = extractPokemonFromNBT(nbt, BukkitNmsConverter.getRegistryAccess());
        if (entry.getPokemon() == null) return;

        if (LGPokemonMenu.getMainConfig().getToPokemon() > 0 && LGPokemonMenu.getEconomy() != null) {
            new ItemToPokemonInventory(entry, bukkitItem).openInventory(player);
            inventory.setItemInMainHand(null);
            event.setCancelled(true);
            return;
        }

        ItemToPokemonEvent itemToPokemonEvent = EventFactory.callItemToPokemonEvent(player, entry.getPokemon());
        if (itemToPokemonEvent.isRemoveItem()) inventory.setItemInMainHand(null);
        if (itemToPokemonEvent.isCancelled()) return;

        entry.run();
        PokemonPlayer pokemonPlayer = PokemonPlayerManger.INSTANCE.getPokemonPlayer(player);
        pokemonPlayer.addPartyPokemon(entry.getPokemon());
        inventory.setItemInMainHand(null);
        event.setCancelled(true);
        player.sendMessage(LGPokemonMenu.getMessage().getModelToPokemon());
    }

    @SneakyThrows
    private static PokemonNBTUtil.Entry extractPokemonFromNBT(class_2487 nbt, class_5455 registryAccess) {
        Pokemon pokemon = null;
        Runnable runnable = null;
        if (nbt.method_10545("pokemon_data") && MainConfig.INSTANCE.isLgPokemonMenu()) {
            String data = nbt.method_10558("pokemon_data");
            JsonObject json = JsonParser.parseString(data).getAsJsonObject();
            pokemon = Pokemon.Companion.loadFromJSON(registryAccess, json);
        } else if (nbt.method_10545("pokemonNBT") && MainConfig.INSTANCE.isYuCobblemonBasis()) {
            String data = nbt.method_10558("pokemonNBT");
            class_2487 compound = class_2522.method_10718(data);
            pokemon = Pokemon.Companion.loadFromNBT(registryAccess, compound);
        } else if (nbt.method_10545("akita-cobblemondata") && MainConfig.INSTANCE.isCobblemonInfo()) {
            String data = nbt.method_10558("akita-cobblemondata");
            byte[] decode = Base64.getDecoder().decode(data);
            ByteArrayInputStream bis = new ByteArrayInputStream(decode);
            DataInputStream dataInput = new DataInputStream(bis);
            class_2487 compound = class_2507.method_10627(dataInput);
            pokemon = Pokemon.Companion.loadFromNBT(registryAccess, compound);
        }

        return new PokemonNBTUtil.Entry(pokemon, runnable);
    }

}